package com.luyang.framework.lock;

import com.google.common.base.Preconditions;
import com.luyang.framework.lock.configuration.RedissonConfigContext;
import com.luyang.framework.lock.configuration.env.ClusterRedissonConfiguration;
import com.luyang.framework.lock.configuration.env.StandaloneRedissonConfiguration;
import com.luyang.framework.lock.enums.ConnectionTypeEnum;
import com.luyang.framework.lock.props.RedissonProperties;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.redisson.config.Config;

import javax.annotation.concurrent.ThreadSafe;

/**
 * Redisson 连接方式配置工厂 单例模式
 *
 * @author lu_yang
 */
@ThreadSafe
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class RedissonConfigFactory {

    private static RedissonConfigFactory factory;

    public static RedissonConfigFactory getInstance() {
        if (null == factory) {
            factory = new RedissonConfigFactory();
        }

        return factory;
    }

    /**
     * 根据连接类型获取对应连接方式的配置 基于策略模式
     *
     * @param redissonProperties redisson配置
     * @return org.redisson.config.Config
     * @author lu_yang
     */
    protected Config createConfig(RedissonProperties redissonProperties) {

        Preconditions.checkNotNull(redissonProperties);
        Preconditions.checkNotNull(redissonProperties.getAddress(), "redisson.lock.server.address 不能为null");
        Preconditions.checkNotNull(redissonProperties.getType(), "redisson.lock.server.password 不能为null");

        var connectionType = ConnectionTypeEnum.getEnumByCode(redissonProperties.getType());

        // 声明配置上下文
        var redissonConfigContext = switch (connectionType) {
            case STANDALONE ->
                new RedissonConfigContext(new StandaloneRedissonConfiguration());
            case CLUSTER ->
                new RedissonConfigContext(new ClusterRedissonConfiguration());
            default ->
                throw new IllegalArgumentException("创建Redisson连接配置失败！当前连接方式:" + connectionType.getCode());
        };

        return redissonConfigContext.buildRedissonConfig(redissonProperties);
    }
}
